package com.eqs.enterprisequestionnaire.service;

import com.eqs.enterprisequestionnaire.model.pojo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

import static com.eqs.enterprisequestionnaire.model.enums.QuestionEnum.isSortType;

@Service
public class DifferenceSortQuestionAnalysisService {
    @Autowired
    private QuestionService questionService;

    @Autowired
    private HistoryService historyService;

    @Autowired
    private UserService userService;

    @Autowired
    private ResponseService responseService;

    // 性别差异化分析
    public Map<Boolean, Map<String, Double>> getGenderDifference(Integer questionId) {
        Question question = questionService.selectByQuestionId(questionId);
        if (!isSortType(question.getType())) {
            return null;
        }

        List<Answer> answers = historyService.getListAnswerByQuestionId(questionId);
        List<Option> options = historyService.getListOptionByQuestionId(questionId);

        Map<Boolean, Map<String, Integer>> totalScores = new HashMap<>();
        Map<Boolean, Map<String, Integer>> countAnswers = new HashMap<>();

        for (Option option : options) {
            totalScores.putIfAbsent(true, new HashMap<>());
            totalScores.putIfAbsent(false, new HashMap<>());
            countAnswers.putIfAbsent(true, new HashMap<>());
            countAnswers.putIfAbsent(false, new HashMap<>());
        }

        for (Answer answer : answers) {
            Response response = responseService.getById(answer.getResponseId());
            User user = userService.getById(response.getUserId());
            Boolean gender = user.getGender();

            String optionId = answer.getContent().trim();
            Option option = options.stream().filter(opt -> opt.getId().toString().equals(optionId)).findFirst().orElse(null);
            String optionContent = option != null ? option.getContent() : "Unknown";

            totalScores.get(gender).put(optionContent, totalScores.get(gender).getOrDefault(optionContent, 0) + Integer.parseInt(answer.getText()));
            countAnswers.get(gender).put(optionContent, countAnswers.get(gender).getOrDefault(optionContent, 0) + 1);
        }

        Map<Boolean, Map<String, Double>> result = new HashMap<>();
        for (Boolean gender : totalScores.keySet()) {
            Map<String, Double> genderResult = new HashMap<>();
            for (String option : totalScores.get(gender).keySet()) {
                int totalScore = totalScores.get(gender).get(option);
                int count = countAnswers.get(gender).get(option);
                genderResult.put(option, count == 0 ? 0.0 : (double) totalScore / count);
            }
            result.put(gender, genderResult);
        }

        return result;
    }

    // 年龄差异化分析
    public Map<String, Map<String, Double>> getAgeDifference(Integer questionId) {
        Question question = questionService.selectByQuestionId(questionId);
        if (!isSortType(question.getType())) {
            return null;
        }

        List<Answer> answers = historyService.getListAnswerByQuestionId(questionId);
        List<Option> options = historyService.getListOptionByQuestionId(questionId);

        Map<String, Map<String, Integer>> totalScores = new HashMap<>();
        Map<String, Map<String, Integer>> countAnswers = new HashMap<>();

        String[] ageStages = {"20-25", "25-30", "30-35","35-40","40-45","45-50","50+"};
        for (String ageStage : ageStages) {
            totalScores.put(ageStage, new HashMap<>());
            countAnswers.put(ageStage, new HashMap<>());
        }

        for (Answer answer : answers) {
            Response response = responseService.getById(answer.getResponseId());
            User user = userService.getById(response.getUserId());
            int age = userService.calculateUserAge(user.getId());

            String ageStage = null;
            if (age >= 20 && age <= 25) {
                ageStage = "20-25";
            } else if (age > 25 && age <= 30) {
                ageStage = "25-30";
            } else if (age > 30 && age <= 35) {
                ageStage = "30-35";
            }else if (age > 35 && age <= 40) {
                ageStage = "35-40";
            }else if (age > 40 && age <= 45) {
                ageStage = "40-45";
            }else if (age > 45 && age <= 50) {
                ageStage = "45-50";
            }else if (age > 50) {
                ageStage = "50+";
            }

            if (ageStage != null) {
                String optionId = answer.getContent().trim();
                Option option = options.stream().filter(opt -> opt.getId().toString().equals(optionId)).findFirst().orElse(null);
                String optionContent = option != null ? option.getContent() : "Unknown";

                totalScores.get(ageStage).put(optionContent, totalScores.get(ageStage).getOrDefault(optionContent, 0) + Integer.parseInt(answer.getText()));
                countAnswers.get(ageStage).put(optionContent, countAnswers.get(ageStage).getOrDefault(optionContent, 0) + 1);
            }
        }

        Map<String, Map<String, Double>> result = new HashMap<>();
        for (String ageStage : totalScores.keySet()) {
            Map<String, Double> ageStageResult = new HashMap<>();
            for (String option : totalScores.get(ageStage).keySet()) {
                int totalScore = totalScores.get(ageStage).get(option);
                int count = countAnswers.get(ageStage).get(option);
                ageStageResult.put(option, count == 0 ? 0.0 : (double) totalScore / count);
            }
            result.put(ageStage, ageStageResult);
        }

        return result;
    }

    // 公司差异化分析
    public Map<String, Map<String, Double>> getEnterpriseDifference(Integer questionId) {
        Question question = questionService.selectByQuestionId(questionId);
        if (!isSortType(question.getType())) {
            return null;
        }

        List<Answer> answers = historyService.getListAnswerByQuestionId(questionId);
        List<Option> options = historyService.getListOptionByQuestionId(questionId);

        Map<String, Map<String, Integer>> totalScores = new HashMap<>();
        Map<String, Map<String, Integer>> countAnswers = new HashMap<>();

        for (Answer answer : answers) {
            Response response = responseService.getById(answer.getResponseId());
            User user = userService.getById(response.getUserId());
            String enterprise = user.getEnterprise();

            String optionId = answer.getContent().trim();
            Option option = options.stream().filter(opt -> opt.getId().toString().equals(optionId)).findFirst().orElse(null);
            String optionContent = option != null ? option.getContent() : "Unknown";

            totalScores.putIfAbsent(enterprise, new HashMap<>());
            countAnswers.putIfAbsent(enterprise, new HashMap<>());

            totalScores.get(enterprise).put(optionContent, totalScores.get(enterprise).getOrDefault(optionContent, 0) + Integer.parseInt(answer.getText()));
            countAnswers.get(enterprise).put(optionContent, countAnswers.get(enterprise).getOrDefault(optionContent, 0) + 1);
        }

        Map<String, Map<String, Double>> result = new HashMap<>();
        for (String enterprise : totalScores.keySet()) {
            Map<String, Double> enterpriseResult = new HashMap<>();
            for (String option : totalScores.get(enterprise).keySet()) {
                int totalScore = totalScores.get(enterprise).get(option);
                int count = countAnswers.get(enterprise).get(option);
                enterpriseResult.put(option, count == 0 ? 0.0 : (double) totalScore / count);
            }
            result.put(enterprise, enterpriseResult);
        }

        return result;
    }

    // 职位差异化分析
    public Map<String, Map<String, Double>> getRoleDifference(Integer questionId) {
        Question question = questionService.selectByQuestionId(questionId);
        if (!isSortType(question.getType())) {
            return null;
        }

        List<Answer> answers = historyService.getListAnswerByQuestionId(questionId);
        List<Option> options = historyService.getListOptionByQuestionId(questionId);

        Map<String, Map<String, Integer>> totalScores = new HashMap<>();
        Map<String, Map<String, Integer>> countAnswers = new HashMap<>();

        for (Answer answer : answers) {
            Response response = responseService.getById(answer.getResponseId());
            User user = userService.getById(response.getUserId());
            String role = user.getRoleName();

            String optionId = answer.getContent().trim();
            Option option = options.stream().filter(opt -> opt.getId().toString().equals(optionId)).findFirst().orElse(null);
            String optionContent = option != null ? option.getContent() : "Unknown";

            totalScores.putIfAbsent(role, new HashMap<>());
            countAnswers.putIfAbsent(role, new HashMap<>());

            totalScores.get(role).put(optionContent, totalScores.get(role).getOrDefault(optionContent, 0) + Integer.parseInt(answer.getText()));
            countAnswers.get(role).put(optionContent, countAnswers.get(role).getOrDefault(optionContent, 0) + 1);
        }

        Map<String, Map<String, Double>> result = new HashMap<>();
        for (String role : totalScores.keySet()) {
            Map<String, Double> roleResult = new HashMap<>();
            for (String option : totalScores.get(role).keySet()) {
                int totalScore = totalScores.get(role).get(option);
                int count = countAnswers.get(role).get(option);
                roleResult.put(option, count == 0 ? 0.0 : (double) totalScore / count);
            }
            result.put(role, roleResult);
        }

        return result;
    }

    // Gender differential analysis
    public Map<Boolean, Map<String, List<Double>>> getGenderDifferenceAnalysis(Integer questionId) {
        Question question = questionService.selectByQuestionId(questionId);
        if (!isSortType(question.getType())) {
            return null;
        }

        List<Answer> answers = historyService.getListAnswerByQuestionId(questionId);
        List<Option> options = historyService.getListOptionByQuestionId(questionId);

        Map<Boolean, Map<String, Integer[]>> genderSortCounts = new HashMap<>();

        for (Option option : options) {
            genderSortCounts.putIfAbsent(true, new HashMap<>());
            genderSortCounts.putIfAbsent(false, new HashMap<>());

            genderSortCounts.get(true).put(option.getContent(), new Integer[options.size()]);
            genderSortCounts.get(false).put(option.getContent(), new Integer[options.size()]);

            Arrays.fill(genderSortCounts.get(true).get(option.getContent()), 0);
            Arrays.fill(genderSortCounts.get(false).get(option.getContent()), 0);
        }

        for (Answer answer : answers) {
            Response response = responseService.getById(answer.getResponseId());
            User user = userService.getById(response.getUserId());
            Boolean gender = user.getGender();

            String optionId = answer.getContent().trim();
            Option option = options.stream().filter(opt -> opt.getId().toString().equals(optionId)).findFirst().orElse(null);
            String optionContent = option != null ? option.getContent() : "Unknown";

            int sortIndex = Integer.parseInt(answer.getText()) - 1; // Assuming sort values are 1-based
            genderSortCounts.get(gender).get(optionContent)[sortIndex]++;
        }

        Map<Boolean, Map<String, List<Double>>> result = new HashMap<>();
        for (Boolean gender : genderSortCounts.keySet()) {
            Map<String, List<Double>> genderResult = new HashMap<>();
            for (String optionContent : genderSortCounts.get(gender).keySet()) {
                Integer[] counts = genderSortCounts.get(gender).get(optionContent);
                int total = Arrays.stream(counts).mapToInt(Integer::intValue).sum();
                List<Double> proportions = new ArrayList<>();
                for (int count : counts) {
                    double proportion = total == 0 ? 0.0 : (double) count / total;
                    proportions.add(proportion);
                }
                genderResult.put(optionContent, proportions);
            }
            result.put(gender, genderResult);
        }

        return result;
    }

    // Age differential analysis
    public Map<String, Map<String, List<Double>>> getAgeDifferenceAnalysis(Integer questionId) {
        Question question = questionService.selectByQuestionId(questionId);
        if (!isSortType(question.getType())) {
            return null;
        }

        List<Answer> answers = historyService.getListAnswerByQuestionId(questionId);
        List<Option> options = historyService.getListOptionByQuestionId(questionId);

        Map<String, Map<String, Integer[]>> ageSortCounts = new HashMap<>();

        String[] ageStages = {"20-25", "25-30", "30-35","35-40","40-45","45-50","50+"};
        for (String ageStage : ageStages) {
            ageSortCounts.put(ageStage, new HashMap<>());
            for (Option option : options) {
                ageSortCounts.get(ageStage).put(option.getContent(), new Integer[options.size()]);
                Arrays.fill(ageSortCounts.get(ageStage).get(option.getContent()), 0);
            }
        }

        for (Answer answer : answers) {
            Response response = responseService.getById(answer.getResponseId());
            User user = userService.getById(response.getUserId());
            int age = userService.calculateUserAge(user.getId());

            String ageStage = null;
            if (age >= 20 && age <= 25) {
                ageStage = "20-25";
            } else if (age > 25 && age <= 30) {
                ageStage = "25-30";
            } else if (age > 30 && age <= 35) {
                ageStage = "30-35";
            }else if (age > 35 && age <= 40) {
                ageStage = "35-40";
            }else if (age > 40 && age <= 45) {
                ageStage = "40-45";
            }else if (age > 45 && age <= 50) {
                ageStage = "45-50";
            }else if (age > 50) {
                ageStage = "50+";
            }

            if (ageStage != null) {
                String optionId = answer.getContent().trim();
                Option option = options.stream().filter(opt -> opt.getId().toString().equals(optionId)).findFirst().orElse(null);
                String optionContent = option != null ? option.getContent() : "Unknown";

                int sortIndex = Integer.parseInt(answer.getText()) - 1; // Assuming sort values are 1-based
                ageSortCounts.get(ageStage).get(optionContent)[sortIndex]++;
            }
        }

        Map<String, Map<String, List<Double>>> result = new HashMap<>();
        for (String ageStage : ageSortCounts.keySet()) {
            Map<String, List<Double>> ageStageResult = new HashMap<>();
            for (String optionContent : ageSortCounts.get(ageStage).keySet()) {
                Integer[] counts = ageSortCounts.get(ageStage).get(optionContent);
                int total = Arrays.stream(counts).mapToInt(Integer::intValue).sum();
                List<Double> proportions = new ArrayList<>();
                for (int count : counts) {
                    double proportion = total == 0 ? 0.0 : (double) count / total;
                    proportions.add(proportion);
                }
                ageStageResult.put(optionContent, proportions);
            }
            result.put(ageStage, ageStageResult);
        }

        return result;
    }

    // Enterprise differential analysis
    public Map<String, Map<String, List<Double>>> getEnterpriseDifferenceAnalysis(Integer questionId) {
        Question question = questionService.selectByQuestionId(questionId);
        if (!isSortType(question.getType())) {
            return null;
        }

        List<Answer> answers = historyService.getListAnswerByQuestionId(questionId);
        List<Option> options = historyService.getListOptionByQuestionId(questionId);

        Map<String, Map<String, Integer[]>> enterpriseSortCounts = new HashMap<>();

        for (Answer answer : answers) {
            Response response = responseService.getById(answer.getResponseId());
            User user = userService.getById(response.getUserId());
            String enterprise = user.getEnterprise();

            String optionId = answer.getContent().trim();
            Option option = options.stream().filter(opt -> opt.getId().toString().equals(optionId)).findFirst().orElse(null);
            String optionContent = option != null ? option.getContent() : "Unknown";

            enterpriseSortCounts.putIfAbsent(enterprise, new HashMap<>());
            enterpriseSortCounts.get(enterprise).putIfAbsent(optionContent, new Integer[options.size()]);
            Arrays.fill(enterpriseSortCounts.get(enterprise).get(optionContent), 0);

            int sortIndex = Integer.parseInt(answer.getText()) - 1; // Assuming sort values are 1-based
            enterpriseSortCounts.get(enterprise).get(optionContent)[sortIndex]++;
        }

        Map<String, Map<String, List<Double>>> result = new HashMap<>();
        for (String enterprise : enterpriseSortCounts.keySet()) {
            Map<String, List<Double>> enterpriseResult = new HashMap<>();
            for (String optionContent : enterpriseSortCounts.get(enterprise).keySet()) {
                Integer[] counts = enterpriseSortCounts.get(enterprise).get(optionContent);
                int total = Arrays.stream(counts).mapToInt(Integer::intValue).sum();
                List<Double> proportions = new ArrayList<>();
                for (int count : counts) {
                    double proportion = total == 0 ? 0.0 : (double) count / total;
                    proportions.add(proportion);
                }
                enterpriseResult.put(optionContent, proportions);
            }
            result.put(enterprise, enterpriseResult);
        }

        return result;
    }

    // Role differential analysis
    public Map<String, Map<String, List<Double>>> getRoleDifferenceAnalysis(Integer questionId) {
        Question question = questionService.selectByQuestionId(questionId);
        if (!isSortType(question.getType())) {
            return null;
        }

        List<Answer> answers = historyService.getListAnswerByQuestionId(questionId);
        List<Option> options = historyService.getListOptionByQuestionId(questionId);

        Map<String, Map<String, Integer[]>> roleSortCounts = new HashMap<>();

        for (Answer answer : answers) {
            Response response = responseService.getById(answer.getResponseId());
            User user = userService.getById(response.getUserId());
            String role = user.getRoleName();

            String optionId = answer.getContent().trim();
            Option option = options.stream().filter(opt -> opt.getId().toString().equals(optionId)).findFirst().orElse(null);
            String optionContent = option != null ? option.getContent() : "Unknown";

            roleSortCounts.putIfAbsent(role, new HashMap<>());
            roleSortCounts.get(role).putIfAbsent(optionContent, new Integer[options.size()]);
            Arrays.fill(roleSortCounts.get(role).get(optionContent), 0);

            int sortIndex = Integer.parseInt(answer.getText()) - 1; // Assuming sort values are 1-based
            roleSortCounts.get(role).get(optionContent)[sortIndex]++;
        }

        Map<String, Map<String, List<Double>>> result = new HashMap<>();
        for (String role : roleSortCounts.keySet()) {
            Map<String, List<Double>> roleResult = new HashMap<>();
            for (String optionContent : roleSortCounts.get(role).keySet()) {
                Integer[] counts = roleSortCounts.get(role).get(optionContent);
                int total = Arrays.stream(counts).mapToInt(Integer::intValue).sum();
                List<Double> proportions = new ArrayList<>();
                for (int count : counts) {
                    double proportion = total == 0 ? 0.0 : (double) count / total;
                    proportions.add(proportion);
                }
                roleResult.put(optionContent, proportions);
            }
            result.put(role, roleResult);
        }

        return result;
    }

}
